package szoftlab4;

import java.util.ArrayList;

/**
 * Az összes atomi építőelem absztrakt ősosztálya.
 * @author Peti
 */
@SuppressWarnings("LeakingThisInConstructor")
public abstract class AtomiElem implements Epitoelem
{
    /**
     * Az atomi elemhez tartozó bemenetek listája.
     */
    protected ArrayList<Bemenet> bemenetek;

    /**
     * Az atomi elemhez tartozó kimenetek listája.
     */
    protected ArrayList<Kimenet> kimenetek;

    /**
     * Az atomi elemet tartalmazó asztal.
     */
    protected Asztal asztal;

    /**
     * Létrehozza a csatlakozók listáit.
     */
    public AtomiElem()
    {
        //Logger.log(this, HivasTipus.Create, "AtomiElem", "AtomiElem()");
        bemenetek = new ArrayList<Bemenet>();
        kimenetek = new ArrayList<Kimenet>();
        //Logger.log(this, HivasTipus.Return, "AtomiElem", "AtomiElem()");
    }

    /**
     * Visszaadja, hogy ez az atomi elem melyik asztalon helyezkedik el.
     *
     * @return
     * Az építőelemet tartalmazó asztal.
     */
    public Asztal getAsztal()
    {
        Logger.log(this, HivasTipus.Call, "Epitoelem", "Asztal getAsztal()");
        try
        {
            return ((Asztal) Logger.objektumvalasztas("Melyik sorszámú objektum az asztal?"));
        }
        catch (Exception e)
        {
            return null;
        }
        finally
        {
            Logger.log(this, HivasTipus.Return, "Epitoelem", "Asztal getAsztal()");
        }
    }

    public ArrayList<Bemenet> szabadBemenetek()
    {
        ArrayList<Bemenet> eredmeny = new ArrayList<Bemenet>();
        for(Bemenet b:bemenetek)
        {
            if(b.getKimenet()==null) eredmeny.add(b);
        }
        return eredmeny;
    }

    public ArrayList<Kimenet> szabadKimenetek()
    {
        ArrayList<Kimenet> eredmeny = new ArrayList<Kimenet>();
        for(Kimenet k:kimenetek)
        {
            if(k.getBemenetek().isEmpty()) eredmeny.add(k);
        }
        return eredmeny;
    }

    /**
     * Csatlakozást kezdeményez egy megadott sorszámú bemenetéről egy másik
     * építőelem megadott sorszámú kimenetére.
     *
     * @param bemenetIndexe
     * A megadott bemenet sorszáma.
     *
     * @param cel
     * A másik építőelem.
     *
     * @param kimenetIndexe
     * A másik építőelem megadott kimenetének sorszáma.
     *
     */
    public abstract void csatlakozik(int bemenetIndexe, Epitoelem cel, int kimenetIndexe);

    /**
     * Csatlakozást fogad egy vezeték megadott sorszámú bemenetéről
     * egy megadott sorszámú kimenetére.
     * 
     * @param bemenetIndexe
     * A kezdeményező vezeték megadott bemenetének sorszáma.
     * 
     * @param innen
     * A kezdeményező vezeték.
     * 
     * @param kimenetIndexe
     * A megadott kimenet sorszáma.
     * 
     * @return
     * A csatlakozásra kijelölt kimenet.
     * 
     */
    public abstract Kimenet csatlakozik(int bemenetIndexe, Vezetek innen, int kimenetIndexe);

    /**
     * Csatlakozást fogad egy nem vezeték típusú építőelem megadott sorszámú
     * bemenetéről egy megadott sorszámú kimenetére.
     * 
     * @param bemenetIndexe
     * A kezdeményező építőelem megadott bemenetének sorszáma.
     * 
     * @param innen
     * A kezdeményező építőelem.
     * 
     * @param kimenetIndexe
     * A megadott kimenet sorszáma.
     * 
     * @return
     * A csatlakozásra kijelölt kimenet.
     * 
     */
    public abstract Kimenet csatlakozik(int bemenetIndexe, NemVezetekEpitoelem innen, int kimenetIndexe);

    /**
     * Az atomi elem logikája a kimenet értékének kiszámítására.
     */
    public abstract void szamol();

    /**
     * Az atomi elem átadja saját magát az EpitoelemAktivVisitor visit metódusának.
     *
     * @param v
     * Az asztal EpitoelemAktivVisitora.
     */
    public abstract void accept(EpitoelemAktivVisitor v);
}
